package org.aldar.bquest.entity;

import org.aldar.bquest.constants.IConstants;
import org.aldar.bquest.entity.effect.ParticleUtil;
import org.aldar.bquest.logic.controller.player.ManaAndPointsController;
import org.aldar.bquest.resources.ResourceManager;
import org.aldar.bquest.screens.MainBoardScreen;
import org.aldar.bquest.util.Logger;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import static org.aldar.bquest.entity.effect.ParticleUtil.showStarRotationEffect;

/**
 * User: Daria
 * Date: 2/4/14 8:14 PM
 */
public abstract class ManaIncreasingTile extends TileSprite {

    private static final Logger LOG = new Logger(ManaIncreasingTile.class);

    public ManaIncreasingTile(int col, int row, ITextureRegion mTileTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager) {
        super(col, row, mTileTextureRegion, pVertexBufferObjectManager);
    }

    @Override
    protected void performMatchAdditionalActions(int col, int row) {
        // FIXME
        // ManaAndPointsController.getInstance().addMana(GameProfile.getCurrentLevel().getManaSettings().getAmountAddForCrystal());

        final float fromX = this.getTile().getX() + 30;
        final float fromY = this.getTile().getY() - 70;
        ManaAndPointsController.getInstance().updateMana();
        showStarRotationEffect(0.3f, 0.5f, fromX, fromY, MainBoardScreen.getScm().getBonusLayer());
        MainBoardScreen.getInstanceEngine().registerUpdateHandler(new TimerHandler(0.3f, new ITimerCallback() {
            @Override
            public void onTimePassed(TimerHandler pTimerHandler) {
                ParticleUtil.makeCrystalPath(IConstants.CRYSTAL_COLLECT_DURATION, fromX, fromY, ManaAndPointsController.MANA_TARGET_X, ManaAndPointsController.MANA_TARGET_Y);

                ParticleUtil.makeParticlePath(fromX, fromY, ManaAndPointsController.MANA_TARGET_X, ManaAndPointsController.MANA_TARGET_Y,
                        ResourceManager.getInstance().getParticleRegion());
            }
        }));
    }

    @Override
    public boolean producesMana() {
        return true;
    }

    @Override
    protected void performDissolveAction(int col, int row) {
        if (isUseDefaultDissolveAction()) {
            setUseDefaultDissolveAction(false);
            getDefaultDissolveAction(col, row).run();
        } else {
            getCrystalDissolveAction(col, row).run();
        }
    }

    public abstract int getManaAmountForMatch();

    public AnimatedSprite.IAnimationListener getAnimationListener(final int totalFrames) {
        return new AnimatedSprite.IAnimationListener() {
            int direction = 1;

            @Override
            public void onAnimationStarted(AnimatedSprite pAnimatedSprite, int pInitialLoopCount) {
            }

            @Override
            public void onAnimationFrameChanged(AnimatedSprite pAnimatedSprite, int pOldFrameIndex, int pNewFrameIndex) {
                if (pNewFrameIndex < pOldFrameIndex) {
                    direction *= -1;
                }
                float approachPercentToMiddle = 1 - Math.abs(totalFrames / 2f - pNewFrameIndex) / (totalFrames / 2f);
                //pAnimatedSprite.setY(pAnimatedSprite.getY() + 0.5f * direction);
                //pAnimatedSprite.setY(direction * 50 * approachPercentToMiddle);
                if (isInMovement()) {
                    return;
                }
                if (!isInDrag()) {
                    getTile().setY((float) (getTileAboveContainer().getY() + (10f * approachPercentToMiddle) * direction));
                } else {
                    getTile().setY(getTileAboveContainer().getY());
                }
            }

            @Override
            public void onAnimationLoopFinished(AnimatedSprite pAnimatedSprite, int pRemainingLoopCount, int pInitialLoopCount) {
            }

            @Override
            public void onAnimationFinished(AnimatedSprite pAnimatedSprite) {
            }
        };
    }

    public void restartAnimation() {
        LOG.i("restart animation called");
        ((AnimatedSprite) getLsSprite()).animate(50, getAnimationListener((((AnimatedSprite) getLsSprite()).getTiledTextureRegion()).getTileCount()));
    }

}
